/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.2 $
 * * DATE
 * *    $Date: 2007/06/13 00:43:31 $
 * * LOG
 * *    $Log: Dispatcher.java,v $
 * *    Revision 1.2  2007/06/13 00:43:31  animesh
 * *    no message
 * *
 * *    Revision 1.8  2006/10/26 23:58:31  lmottola
 * *    Bug fixes: Hello World application running in SWANS.
 * *
 * *    Revision 1.7  2006/10/25 22:06:52  animesh
 * *    made dispatchDataItems a wrapper of sendData()
 * *
 * *    Revision 1.6  2006/10/25 19:35:06  animesh
 * *    Changed the code to use logical neighborhoods. Still needs some work
 * *
 * *    Revision 1.5  2006/10/24 22:36:07  animesh
 * *    Changed functions for sending out data. Used a lot of old code, but Luca will have to integrate it.
 * *
 * *    Revision 1.4  2006/10/24 09:57:44  animesh
 * *    Changed functions for sending out data. Used a lot of old code, but Luca will have to integrate it.
 * *
 * *    Revision 1.3  2006/10/19 21:21:52  lmottola
 * *    Added CVS preamble.
 * *
 * *
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 * *   This program is free software; you can redistribute it and/or
 * *   modify it under the terms of the GNU General Public License
 * *   as published by the Free Software Foundation; either version 2
 * *   of the License, or (at your option) any later version.
 * *
 * *   This program is distributed in the hope that it will be useful,
 * *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * *   GNU General Public License for more details.
 * *
 * *   You should have received a copy of the GNU General Public License
 * *   along with this program; if not, you may find a copy at the FSF web
 * *   site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
 * *   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * *   Boston, MA  02111-1307, USA
 ***/

package atag.runtime;

import atag.runtime.ln.*;
import atag.common.ScopedChannel;
import atag.runtime.ln.neighborhoodDefs.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class Dispatcher {

	private static LogicalNeighborhoods ln;

	private static AtagManager m_AtagManager;

	private static NodeInfo m_config;

	public Dispatcher(LogicalNeighborhoods ln, AtagManager t_AtagManager,
			NodeInfo t_config) {

		this.ln = ln;
		this.m_AtagManager = t_AtagManager;
		this.m_config = t_config;
	}

	public void newInstanceProduced(DataItem t_dataItem) {

		// ******* LUCA: asks the ATaG manager about the scope of this data
		// item,
		// and calls LNs.

		// Animesh -- the code below is from the original dispatcher. Needs to
		// be merged properly.

		/**
		 * Perform sanity check for output channel that produced this data.
		 * Whether the output channel is local or non-local is not the
		 * Dispatcher's concern; it is the ATaGManager. The Dispatcher is
		 * interested in 2 things only: if there is some non-"NONE" interest
		 * associated with this channel if there is some destination ID
		 * specified by the compiler for this data In the former case, translate
		 * the annotation and generate list of node IDs In the latter case, the
		 * list is already provided.
		 */

		int dataID = t_dataItem.dataID();
		// ScopedChannel t_channelDecl =
		// m_AtagManager.getOutputChannelDeclaration(t_dataItem.
		// producerID(), dataID);

		Neighborhood[] destinationScopes = this.m_AtagManager.getLNScopeForData(
				t_dataItem.producerID(), dataID);

		if (!(destinationScopes == null)) {
			// The task needs to go somewhere non-local
            ByteArrayOutputStream byteStream= new ByteArrayOutputStream();
            DataOutputStream dg=new DataOutputStream(byteStream);
            try {
                t_dataItem.serialize(dg);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
			// send out the dataitem to the interest.
			this.ln.send(byteStream.toByteArray(), destinationScopes);

		}

		// why is this code here? -- Animesh? It seems that we are sending data
		// twice.
		// Is it because networkarch would not be doing any job till now?
		/*
		 * nodeIDs = m_config.getDestinationOfData(dataID); if (nodeIDs != null)
		 * //System.out.println("No destinations for this data item"); //else {
		 * //System.out.println(nodeIDs.length + " destinations specified.");
		 * this.dispatchMultipleDataItems(nodeIDs, t_dataItem); //}
		 * 
		 */
		return;
	}

	/**
	 * For sending data items to a set of nodes Creates a bunch of messages and
	 * sends them out one by one
	 */
	/*
	 * Animesh commented this out since we are not dispatching on node basis
	 * anymore
	 * 
	 * private void dispatchMultipleDataItems(int[] nodeIDs, DataItem
	 * t_dataitem) { //System.out.println("NetworkStack: Sending data to " +
	 * nodeIDs.length + " nodes"); for (int ctr=0; ctr<nodeIDs.length; ctr++) {
	 * //System.out.println("Calling xmitdata for ID: " + nodeIDs[ctr]);
	 * 
	 * 
	 * 
	 * 
	 * NetworkMessageContent msg = new DARTMessage(nodeIDs[ctr],t_dataitem);
	 * 
	 * m_networkStack.sendData(nodeIDs[ctr],NetworkMessage.DART_MESSAGE,msg);
	 * 
	 * //m_transmitter.transmitData(nodeIDs[ctr], //
	 * NetworkMessage.DART_MESSAGE);
	 *  }
	 *  }
	 */
//
//	private void dispatchDataItems(DataItem t_dataItem, LNScope[] targetLNScopes) {
//		/*
//		 * original code...
//		 * 
//		 * NetworkMessageContent msg = new DARTMessage(nodeIDs[ctr],t_dataitem);
//		 * 
//		 * m_networkStack.sendData(nodeIDs[ctr],NetworkMessage.DART_MESSAGE,msg);
//		 */
//
//		// Suppose this node has HS = 4, and wants to send data to the
//		// traffic lights in the same and adjacent HSs
//		// LNPredicate highWaySector = new IntegerRangePredicate("HS", 3, 5);
//		// LNPredicate trafficLight = new SetMembershipPredicate(
//		// "TrafficLight", SetMembershipPredicate.IS_IN,
//		// "attachedActuators");
//		// LNScope trafficLightsAdjacentHSs = new LNScope(new LNPredicate[] {
//		// highWaySector, trafficLight });
//		// this.ln.sendData(new DataItem(0, 0, null),
//		// new LNScope[] { trafficLightsAdjacentHSs });
//		this.ln.sendData(t_dataItem, targetLNScopes);
//
//		// this makes the function look like a wrapper .. but maybe that is fine
//
//	}

}
